#ifndef DATABASEMANAGER_H
#define DATABASEMANAGER_H

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QString>
#include <QVariant>
#include <QMutex>
#include <QThreadStorage>
#include <QAtomicInt>
#include "models.h"

class DatabaseManager {
public:
    static DatabaseManager& instance();
    
    bool connectToDatabase(const QString& host, int port, const QString& dbName, 
                           const QString& user, const QString& password);
    void closeDatabase();
    bool isConnected() const;
    
    // 为当前线程获取数据库连接（线程安全）
    QSqlDatabase getThreadDatabase();
    
    // 用户认证
    bool authenticateUser(const QString& username, const QString& password, User& user);
    bool registerUser(const User& user);
    
    // 患者相关
    bool getPatientInfo(int patientId, Patient& patient);
    bool updatePatientInfo(const Patient& patient);
    bool createAppointment(const Appointment& appointment, int& appointmentId);
    bool cancelAppointment(int appointmentId);
    bool cancelAppointmentsInRange(int doctorId, const QDate& startDate, const QDate& endDate); // 批量取消预约
    bool updateAppointmentStatus(int appointmentId, const QString& status);
    void checkAppointmentCompletion(int appointmentId, bool& hasRecord, bool& hasPrescription);
    
    // 医患沟通相关
    QList<Doctor> getAllDoctors();                                      // 获取所有医生
    QList<Patient> getChatPatients(int doctorId);                       // 获取医生的聊天患者列表
    bool sendMessage(const Message& message);                           // 发送消息
    QList<Message> getChatHistory(int userId1, int userId2);           // 获取聊天历史
    int getUnreadCount(int receiverId, int senderId = 0);              // 获取未读消息数
    bool markAsRead(int receiverId, int senderId);                      // 标记消息为已读
    QList<Appointment> getPatientAppointments(int patientId);
    QList<MedicalRecord> getPatientMedicalRecords(int patientId);
    QList<Prescription> getPatientPrescriptions(int patientId);
    
    // 医生相关
    bool getDoctorInfo(int doctorId, Doctor& doctor);
    bool updateDoctorInfo(const Doctor& doctor);
    QList<Appointment> getDoctorAppointments(int doctorId, const QDate& date);
    bool createMedicalRecord(const MedicalRecord& record, int& recordId);
    bool createPrescription(const Prescription& prescription);
    bool createExamRequest(const ExamRequest& exam);
    
    // 科室相关
    QList<Department> getAllDepartments();
    QList<Doctor> getDoctorsByDepartment(int departmentId);
    
    // 缴费相关
    bool createPayment(const Payment& payment);
    QList<Payment> getPatientPayments(int patientId);
    
    // 考勤相关
    bool checkIn(int doctorId);                                         // 打卡
    bool cancelCheckIn(int doctorId, const QDate& date);               // 取消打卡
    QList<AttendanceRecord> getAttendanceRecords(int doctorId, const QDate& startDate, const QDate& endDate);  // 获取打卡记录
    bool getTodayAttendance(int doctorId, AttendanceRecord& record);   // 获取今日打卡状态
    bool createLeaveRequest(const LeaveRequest& request);              // 创建请假申请
    bool cancelLeaveRequest(int requestId);                            // 取消请假申请
    QList<LeaveRequest> getLeaveRequests(int doctorId);                // 获取请假记录
    bool cancelLeave(int requestId);                                   // 销假
    
    // 药物查询相关
    QList<Medicine> getPopularMedicines();                             // 获取热门药物
    QList<Medicine> searchMedicines(const QString& keyword);           // 搜索药物
    
    // 通知相关
    bool createNotification(const Notification& notification);         // 创建通知
    QList<Notification> getUserNotifications(int userId, int userRole); // 获取用户通知列表
    bool markNotificationRead(int notificationId);                     // 标记通知为已读
    bool clearAllNotifications(int userId, int userRole);              // 清空所有通知
    int getUnreadNotificationCount(int userId, int userRole);          // 获取未读通知数量
    
    // 考勤与预约关联
    bool isDoctorOnLeave(int doctorId, const QDate& date);            // 检查医生是否请假
    QList<Appointment> getDoctorAppointmentsInRange(int doctorId, const QDate& startDate, const QDate& endDate); // 获取时间段内的预约
    
    QString lastError() const { return m_lastError; }
    
private:
    DatabaseManager();
    ~DatabaseManager();
    DatabaseManager(const DatabaseManager&) = delete;
    DatabaseManager& operator=(const DatabaseManager&) = delete;
    
    QSqlDatabase m_database;  // 主线程连接
    QString m_lastError;
    
    // 数据库连接参数（用于创建线程本地连接）
    QString m_host;
    int m_port;
    QString m_dbName;
    QString m_user;
    QString m_password;
    bool m_isConfigured;
    
    QMutex m_mutex;
    static QAtomicInt m_connectionCounter;  // 用于生成唯一连接名
};

#endif // DATABASEMANAGER_H

